package capaPresentacion.client.presentador;

import java.util.List;

import capaPresentacion.client.WorldsTrainerWebServiceAsync;
import capaPresentacion.client.evento.EventoLogout;
import capaPresentacion.shared.ComentarioDTO;
import capaPresentacion.shared.RutaDTO;
import capaPresentacion.shared.UsuarioDTO;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.MenuItem;
import com.google.gwt.user.client.ui.Widget;

public class PresentadorAdministrador implements Presentador {

	private final WorldsTrainerWebServiceAsync rpcService;
	private final HandlerManager eventBus;
	private final Display display;

	public interface Display {

		HasClickHandlers getBotonBuscarDialogoRuta();

		HasClickHandlers getBotonBuscarDialogoUsuario();

		HasClickHandlers getBotonEliminarUsuario();

		HasClickHandlers getBotonEliminarRuta();

		HasClickHandlers getBotonVerComentarios();

		HasClickHandlers getBotonEliminarComentario();

		MenuItem logout();

		String getEmailUsuarioAEliminar();

		Long getIdRuta();

		Long getIdComentarioAEliminar();

		HasValue<String> getNombreRutaBusqueda();

		HasValue<String> getNombreUsuarioBusqueda();

		void comentarios(List<ComentarioDTO> comentariosdto);

		void buscarRuta(List<RutaDTO> rutasDTO);

		void buscarUsuario(List<UsuarioDTO> usuariosDTO);

		void ocultarDialogo(String rutaOUsuario);

		void resetIdRutaAEliminar();

		void resetEmailUsuarioAEliminar();

		void resetComentarioAEliminar();

		Widget asWidget();
	}

	public PresentadorAdministrador(WorldsTrainerWebServiceAsync rpcService,
			HandlerManager eventBus, Display display) {

		this.rpcService = rpcService;
		this.eventBus = eventBus;
		this.display = display;
		bind();
	}

	@Override
	public void go(HasWidgets container) {
		container.clear();
		container.add(display.asWidget());
	}

	private void bind() {
		this.display.logout().setCommand(new Command() {
			@Override
			public void execute() {
				doLogout();
			}
		});
		this.display.getBotonBuscarDialogoRuta().addClickHandler(
				new ClickHandler() {
					@Override
					public void onClick(ClickEvent event) {
						doBuscarRuta();

					}
				});
		this.display.getBotonBuscarDialogoUsuario().addClickHandler(
				new ClickHandler() {
					@Override
					public void onClick(ClickEvent event) {
						doBuscarUsuario();
					}
				});
		this.display.getBotonEliminarUsuario().addClickHandler(
				new ClickHandler() {
					@Override
					public void onClick(ClickEvent event) {
						doEliminarUsuario();
					}
				});
		this.display.getBotonEliminarRuta().addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				doEliminarRuta();
			}
		});
		this.display.getBotonVerComentarios().addClickHandler(
				new ClickHandler() {
					@Override
					public void onClick(ClickEvent event) {
						doVerComentario();
					}
				});
		this.display.getBotonEliminarComentario().addClickHandler(
				new ClickHandler() {
					@Override
					public void onClick(ClickEvent event) {
						doEliminarComentario();
					}
				});
	}

	protected void doEliminarComentario() {
		long id = display.getIdComentarioAEliminar();
		if (id != (long) -1) {
			rpcService.borrarComentarioDTO(id, new AsyncCallback<Void>() {
				@Override
				public void onSuccess(Void result) {
					display.resetComentarioAEliminar();
					doVerComentario();
				}

				@Override
				public void onFailure(Throwable caught) {
					Window.alert("Error eliminando comentario");
				}
			});
		}
	}

	protected void doVerComentario() {
		long id = display.getIdRuta();
		if (id != (long) -1) {
			rpcService.obtenerComentariosRuta(id,
					new AsyncCallback<List<ComentarioDTO>>() {
						@Override
						public void onSuccess(List<ComentarioDTO> result) {
							display.comentarios(result);
						}

						@Override
						public void onFailure(Throwable caught) {
							Window.alert("Error obteniendo comentarios");
						}
					});
		}
	}

	protected void doEliminarRuta() {
		final long id = display.getIdRuta();
		if (id != (long) -1) {
			rpcService.borrarRuta(id, new AsyncCallback<Void>() {
				@Override
				public void onSuccess(Void result) {
					display.resetIdRutaAEliminar();
					doBuscarRuta();
				}

				@Override
				public void onFailure(Throwable caught) {
					Window.alert("Error al eleiminar ruta" + id);
				}
			});
		}
	}

	protected void doEliminarUsuario() {
		String email = display.getEmailUsuarioAEliminar();
		if (!email.equals("Ninguno")) {
			rpcService.borrarUsuario(email, new AsyncCallback<Void>() {
				@Override
				public void onSuccess(Void result) {
					display.resetEmailUsuarioAEliminar();
					doBuscarUsuario();
				}

				@Override
				public void onFailure(Throwable caught) {
					Window.alert("Error al eleiminar usuario");
				}
			});
		}
	}

	protected void doBuscarUsuario() {
		rpcService.buscarUsuariosDTO(display.getNombreUsuarioBusqueda()
				.getValue(), new AsyncCallback<List<UsuarioDTO>>() {
			@Override
			public void onSuccess(List<UsuarioDTO> result) {
				display.buscarUsuario(result);
				display.ocultarDialogo("Usuario");
			}

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Error al realizar la busqueda de usuario");
			}
		});
	}

	public void doBuscarRuta() {
		rpcService.buscarRuta(display.getNombreRutaBusqueda().getValue(),
				new AsyncCallback<List<RutaDTO>>() {
					@Override
					public void onSuccess(List<RutaDTO> result) {
						display.buscarRuta(result);
						display.ocultarDialogo("Ruta");
					}

					@Override
					public void onFailure(Throwable caught) {
						Window.alert("Error al realizar la busqueda de ruta");
					}
				});
	}

	protected void doLogout() {
		rpcService.logoutAdministrador(new AsyncCallback<Void>() {
			@Override
			public void onSuccess(Void result) {
				eventBus.fireEvent(new EventoLogout());
			}

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("No estas logeado");
			}
		});
	}
}
